package cn.ug.analyse.service.impl;

import cn.ug.analyse.bean.ChannelRewardsBean;
import cn.ug.analyse.bean.ChannelSettleBean;
import cn.ug.analyse.bean.SettleBean;
import cn.ug.analyse.mapper.ChannelMapper;
import cn.ug.analyse.mapper.SettleMapper;
import cn.ug.analyse.mapper.entity.ChannelEntity;
import cn.ug.analyse.mapper.entity.ChannelPeriodEntity;
import cn.ug.analyse.mapper.entity.QuerySubmit;
import cn.ug.analyse.mapper.entity.SettleEntity;
import cn.ug.analyse.service.SettleService;
import cn.ug.analyse.web.submit.ChannelSubmit;
import cn.ug.analyse.web.submit.OtherSubmit;
import cn.ug.analyse.web.submit.SettleSubmit;
import cn.ug.bean.LoginBean;
import cn.ug.bean.base.DataTable;
import cn.ug.bean.base.Page;
import cn.ug.bean.base.SerializeObject;
import cn.ug.bean.type.ResultType;
import cn.ug.core.SerializeObjectError;
import cn.ug.core.login.LoginHelper;
import cn.ug.service.impl.BaseServiceImpl;
import org.apache.commons.lang3.StringUtils;
import org.dozer.DozerBeanMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * 渠道结算记录
 *
 * @author zhaohg
 * @date 2018/08/11.
 */
@Service
public class SettleServiceImpl extends BaseServiceImpl implements SettleService {

    @Resource
    private SettleMapper    settleMapper;
    @Resource
    private ChannelMapper   channelMapper;
    @Resource
    private DozerBeanMapper dozerBeanMapper;

    @Override
    public SerializeObject findList(OtherSubmit submit) {
        QuerySubmit querySubmit = new QuerySubmit();
        submit.setSettleParams(querySubmit);

        int count = settleMapper.count(querySubmit);
        Page page = new Page(submit.getPageNum(), submit.getPageSize(), count);
        List<SettleBean> list = new ArrayList<>();
        this.settleData(querySubmit, count, list);

        return new SerializeObject<>(ResultType.NORMAL, "00000001", new DataTable<>(page, list));
    }

    @Override
    public List<SettleBean> export(OtherSubmit submit) {
        QuerySubmit querySubmit = new QuerySubmit();
        submit.setSettleParams(querySubmit);
        querySubmit.setLimit(null, null);

        int count = settleMapper.count(querySubmit);
        List<SettleBean> list = new ArrayList<>();
        this.settleData(querySubmit, count, list);
        return list;

    }

    private void settleData(QuerySubmit querySubmit, int count, List<SettleBean> list) {
        if (count > 0) {
            List<SettleEntity> settleEntities = settleMapper.findList(querySubmit);
            for (SettleEntity entity : settleEntities) {
                SettleBean bean = dozerBeanMapper.map(entity, SettleBean.class);
                list.add(bean);
            }
        }
    }

    @Override
    @Transactional
    public SerializeObject insert(SettleSubmit submit) {

        LoginBean loginBean = LoginHelper.getLoginBean();
        if (loginBean == null || StringUtils.isEmpty(loginBean.getId())) {
            return new SerializeObjectError<>("00000102");
        }

        if (submit.getAmount() == null || submit.getAmount().compareTo(BigDecimal.ZERO) <= 0) {
            return new SerializeObjectError("210000011");
        }

        ChannelEntity channel = channelMapper.findById(submit.getChannelId());
        if (channel == null || submit.getAmount().compareTo(channel.getWaitReward()) > 0) {
            return new SerializeObjectError("210000010");
        }

        SettleEntity entity = new SettleEntity();
        entity.setChannelId(submit.getChannelId());
        entity.setAmount(submit.getAmount());
        entity.setSettleUserId(loginBean.getId());
        entity.setSettleUserName(loginBean.getName());
        int success = settleMapper.insert(entity);
        if (success > 0) {
            channelMapper.settleChannelReward(submit.getChannelId(), submit.getAmount());
        }
        return new SerializeObject<>(ResultType.NORMAL, "00000001");
    }

    @Override
    public SerializeObject findChannelSettleList(ChannelSubmit submit) {
        QuerySubmit querySubmit = new QuerySubmit();
        submit.setChannelSettleParams(querySubmit);

        int count = channelMapper.count(querySubmit);
        Page page = new Page(submit.getPageNum(), submit.getPageSize(), count);
        List<ChannelSettleBean> list = new ArrayList<>(count);
        this.channelSettleData(querySubmit, count, list);

        return new SerializeObject<>(ResultType.NORMAL, "00000001", new DataTable<>(page, list));
    }

    @Override
    public SerializeObject findChannelSettleTotal(ChannelSubmit submit) {
        QuerySubmit querySubmit = new QuerySubmit();
        submit.setChannelSettleParams(querySubmit);
        ChannelEntity entity = channelMapper.findTotal(querySubmit);

        Map<String, Object> map = new HashMap<>();
        if (entity != null) {
            map.put("totalReward", entity.getTotalReward());
            map.put("settleReward", entity.getSettleReward());
            map.put("waitReward", entity.getWaitReward());
        }

        return new SerializeObject<>(ResultType.NORMAL, "00000001", map);
    }

    @Override
    public List<ChannelSettleBean> exportChannelSettleList(ChannelSubmit submit) {
        QuerySubmit querySubmit = new QuerySubmit();
        submit.setChannelSettleParams(querySubmit);
        querySubmit.setLimit(null, null);

        int count = channelMapper.count(querySubmit);
        List<ChannelSettleBean> list = new ArrayList<>(count);
        this.channelSettleData(querySubmit, count, list);

        return list;
    }

    private void channelSettleData(QuerySubmit querySubmit, int count, List<ChannelSettleBean> list) {
        if (count > 0) {
            List<ChannelEntity> channelList = channelMapper.findList(querySubmit);
            Iterator<ChannelEntity> iterator = channelList.iterator();
            while (iterator.hasNext()) {
                ChannelEntity next = iterator.next();
                ChannelSettleBean bean = dozerBeanMapper.map(next, ChannelSettleBean.class);
                list.add(bean);
            }
        }
    }

    /**
     * 渠道周期奖励
     *****/

    @Override
    public SerializeObject findChannelPeriodList(OtherSubmit submit) {
        QuerySubmit querySubmit = new QuerySubmit();
        submit.setChannelPeriodParams(querySubmit);

        int count = settleMapper.getChannelPeriodCount(querySubmit);
        Page page = new Page(submit.getPageNum(), submit.getPageSize(), count);
        List<ChannelPeriodEntity> list = new ArrayList<>();
        if (count > 0) {
            list = settleMapper.getChannelPeriodList(querySubmit);
        }
        return new SerializeObject<>(ResultType.NORMAL, "00000001", new DataTable<>(page, list));
    }

    @Override
    public ChannelPeriodEntity getChannelPeriodByDate(Long channelId, Date startDate, Date endDate) {
        return settleMapper.getChannelPeriodByDate(channelId, startDate, endDate);
    }

    @Transactional
    @Override
    public int addChannelPeriod(ChannelPeriodEntity period) {
        int success = settleMapper.addChannelPeriod(period);
        //并累加到渠道总奖励
        if (success > 0) {
            return channelMapper.addChannelReward(period.getChannelId(), period.getRewardTotalAmount());
        }
        return 0;
    }

    @Override
    public BigDecimal sumOfAmount(int channelId) {
        if (channelId > 0) {
            return settleMapper.sumOfAmount(channelId);
        }
        return null;
    }

    @Override
    public List<ChannelRewardsBean> queryForList(int channelId, int offset, int size) {
        if (channelId > 0) {
            Map<String, Object> params = new HashMap<String, Object>();
            params.put("channelId", channelId);
            params.put("offset", offset);
            params.put("size", size);
            return settleMapper.queryForList(params);
        }
        return null;
    }

    @Override
    public ChannelRewardsBean selectRewardsDetail(int channelId, String month) {
        if (channelId > 1 && StringUtils.isNotBlank(month)) {
            return settleMapper.selectRewardsDetail(channelId, month);
        }
        return null;
    }

    @Override
    public int queryForCount(int channelId) {
        if (channelId > 0) {
            Map<String, Object> params = new HashMap<String, Object>();
            params.put("channelId", channelId);
            return settleMapper.queryForCount(params);
        }
        return 0;
    }
}
